package com.feng.cloud.system.controller;

import com.feng.cloud.common.annotation.ControllerEndpoint;
import com.feng.cloud.common.exception.system.ParameterException;
import com.feng.cloud.common.exception.system.SystemStatus;
import com.feng.cloud.common.request.QueryRequest;
import com.feng.cloud.common.response.RestResponse;
import com.feng.cloud.common.response.TableResultResponse;
import com.feng.cloud.common.utils.FileUtils;
import com.feng.cloud.common.utils.WebUtils;
import com.feng.cloud.system.constant.GeneratorConstant;
import com.feng.cloud.system.entity.Column;
import com.feng.cloud.system.entity.GeneratorConfig;
import com.feng.cloud.system.entity.Table;
import com.feng.cloud.system.helper.GeneratorHelper;
import com.feng.cloud.system.service.GeneratorConfigService;
import com.feng.cloud.system.service.GeneratorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;

/**
 * @ClassName GeneratorController
 * @Description TODO
 * @Author Better Feng
 * @Date 2019/12/23 13:52
 * @Version 1.0
 **/
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("generator")
public class GeneratorController {

    private static final String SUFFIX = "_code.zip";

    private final GeneratorService generatorService;
    private final GeneratorConfigService generatorConfigService;
    private final GeneratorHelper generatorHelper;

    /**
     * 查询所有数据库
     * @return List<String>
     */
    @GetMapping("database")
    @PreAuthorize("hasAuthority('gen:generate')")
    public RestResponse<List<String>> selectDatabase() {
        return new RestResponse<List<String>>().data(generatorService.getDatabases());
    }

    @GetMapping("page")
    @PreAuthorize("hasAuthority('gen:generate')")
    public TableResultResponse<Table> selectList(@RequestParam Map<String, Object> params) {
        QueryRequest request = new QueryRequest(params);
        return generatorService.selectList(request);
    }

    @PostMapping
    @PreAuthorize("hasAuthority('gen:generate:gen')")
    @ControllerEndpoint(operation = "生成代码", exceptionMessage = "代码生成失败")
    public void generate(@NotBlank(message = "{required}") String name,
                         @NotBlank(message = "{required}") String serviceName,
                         String remark, HttpServletResponse response) throws Exception {
        GeneratorConfig generatorConfig = generatorConfigService.findConfigByServiceName(serviceName);
        if (generatorConfig == null) {
            throw new ParameterException(SystemStatus.GENERATOR_CONFIG_NULL);
        }

        String className = name;
        if (GeneratorConfig.TRIM_YES.equals(generatorConfig.getIsTrim())) {
            className = RegExUtils.replaceFirst(name, generatorConfig.getTrimValue(), StringUtils.EMPTY);
        }

        generatorConfig.setTableName(name);
        generatorConfig.setClassName(WebUtils.underscoreToCamel(className));
        generatorConfig.setTableComment(remark);
        // 生成代码到临时目录
        List<Column> columns = generatorService.getColumns(generatorConfig.getTableSchema(), name);
        generatorHelper.generateEntityFile(columns, generatorConfig);
        generatorHelper.generateMapperFile(columns, generatorConfig);
        generatorHelper.generateMapperXmlFile(columns, generatorConfig);
        generatorHelper.generateServiceFile(columns, generatorConfig);
        generatorHelper.generateControllerFile(columns, generatorConfig);
        generatorHelper.generateControllerImplFile(columns, generatorConfig);
        // 打包
        String zipFile = System.currentTimeMillis() + SUFFIX;
        FileUtils.compress(GeneratorConstant.TEMP_PATH + "src", zipFile);
        // 下载
        FileUtils.download(zipFile, name + SUFFIX, true, response);
        // 删除临时目录
        FileUtils.delete(GeneratorConstant.TEMP_PATH);
    }
}
